﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Runtime.Serialization;

namespace AMSService.model
{
    [DataContract (IsReference=true)]//(Namespace="AMSService.model")]
    public class Asset : DBConnector
    {
        private int _id = 0;
        private string _meta;
        private string _name;
        private string _mdl;
        private string _manuf;
        private string _make;
        private string _serial;
        private DateTime _year;
        private string _comments;
        private User _user;
        private List<WarrantyData> _warrdata;
        private List<ServiceData> _servdata;
        private List<ScheduleData> _scheddata;
        private List<PurchaseData> _purchdata;
        private List<AMSImage> _images;

        // Stored procedure name
        private const string _spgetassetbyid = "GetAssetById";
        private const string _spdelassetbyid = "DeleteAssetById";
        private const string _spinsasset = "InsertAsset";
        private const string _spupdasset = "UpdateAsset";

        // Stored procedure arguments
        private const string _prmid = "@id";
        private const string _prmarg = "@arg";
        private const string _prmmeta = "@meta";
        private const string _prmname = "@name";
        private const string _prmmodel = "@model";
        private const string _prmmanuf = "@manuf";
        private const string _prmmake = "@make";
        private const string _prmserial = "@serial";
        private const string _prmyear = "@year";
        private const string _prmcomm = "@comm";
        private const string _prmuserid = "@user";

        // Table field names
        private const string _fldid = "pkid";
        private const string _fldmeta = "metadata";
        private const string _fldnm = "asstname";
        private const string _fldmodel = "modelnum";
        private const string _fldmanuf = "manuf";
        private const string _fldmake = "make";
        private const string _fldsn = "serialnum";
        private const string _fldyear = "asstyear";
        private const string _fldcomm = "comments";
        private const string _flduserid = "fkuser";

        // Stored procedure enumeration
        public enum _spargs { id, userid };

        public Asset(User Owner)
        {
            _user = Owner;
            _id = 0;
            InitializeAttributes();
        }

        public Asset(User Owner, int ID)
        {
            _user = Owner;
            InitializeAttributes();
            FillAsset(ID);
        }

        public Asset(User Owner, DataRow Row)
        {
            _user = Owner;
            InitializeAttributes();
            FillAsset(Row);
        }

        public static string SpSelect
        {
            get { return _spgetassetbyid; }
        }

        public static string SpPrmId
        {
            get { return _prmid; }
        }

        public static string SpPrmArg
        {
            get { return _prmarg; }
        }

        [DataMember]
        public int ID
        {
            get { return _id; }
            set { _id = value; }
        }

        public static string FieldUserId
        {
            get { return _flduserid; }
        }

        public static string ArgUserId
        {
            get { return _prmuserid; }
        }

        [DataMember]
        public string Metadata
        {
            get { return _meta; }
            set { _meta = value; }
        }

        [DataMember]
        public string Name
        {
            get { return _name; }
            set { if (value.Length > 0) { _name = value; } }
        }

        [DataMember]
        public string Model
        {
            get { return _mdl; }
            set { if (value.Length > 0) { _mdl = value; } }
        }

        [DataMember]
        public string Manufacturer
        {
            get { return _manuf; }
            set { if (value.Length > 0) { _manuf = value; } }
        }

        [DataMember]
        public string SerialNumber
        {
            get { return _serial; }
            set { if (value.Length > 0) { _serial = value; } }
        }

        [DataMember]
        public string Make
        {
            get { return _make; }
            set { if (value.Length > 0) { _make = value; } }
        }

        [DataMember]
        public DateTime Year
        {
            get { return _year; }
            set { _year = value; }
        }

        [DataMember]
        public string Comments
        {
            get { return _comments; }
            set { _comments = value; }
        }

        [DataMember]
        public User Owner
        {
            get { return _user; }
            set { if (value != null) { _user = value; } }
        }

        [DataMember]
        public List<WarrantyData> Warranties
        {
            get { return _warrdata; }
            private set { }
        }

        [DataMember]
        public List<ServiceData> Services
        {
            get { return _servdata; }
            private set { }
        }

        [DataMember]
        public List<ScheduleData> Schedules
        {
            get { return _scheddata; }
            private set { }
        }

        [DataMember]
        public List<PurchaseData> Purchases
        {
            get { return _purchdata; }
            private set { }
        }

        [DataMember]
        public List<AMSImage> Images
        {
            get { return _images; }
            private set { }
        }

        public bool Delete()
        {
            List<SqlParameter> paramlist = new List<SqlParameter>();
            SqlParameter pid = new SqlParameter(_prmid, _id);
            paramlist.Add(pid);

            return SendWriteRequest(_spdelassetbyid, paramlist) > 0;
        }

        private void FillAsset(DataRow dr)
        {
            _id = Convert.ToInt32(dr[_fldid].ToString());
            _meta = Convert.ToString(dr[_fldmeta]);
            _name = dr[_fldnm].ToString();
            _mdl = dr[_fldmodel].ToString();
            _manuf = dr[_fldmanuf].ToString();
            _serial = dr[_fldsn].ToString();
            _make = dr[_fldmake].ToString();
            _year = Convert.ToDateTime(dr[_fldyear].ToString());
            _comments = dr[_fldcomm].ToString();
        }

        private void FillAsset(int ID)
        {
            List<SqlParameter> paramlist = new List<SqlParameter>();
            SqlParameter pid = new SqlParameter(_prmid, _id);
            SqlParameter parg = new SqlParameter(_prmarg, _spargs.id);
            paramlist.Add(pid);
            paramlist.Add(parg);
            DataTable dt = SendReadRequest(_spgetassetbyid, paramlist);

            if (dt.Rows.Count > 0)
            {
                FillAsset(dt.Rows[0]);
            }
        }

        private void InitializeAttributes()
        {
            _warrdata = new List<WarrantyData>();
            _servdata = new List<ServiceData>();
            _scheddata = new List<ScheduleData>();
            _purchdata = new List<PurchaseData>();
            _images = new List<AMSImage>();
        }

        public void LoadImages()
        {
            DataTable dt = SendReadRequest(AMSImage.SpSelect,
                new SqlParameter[] { new SqlParameter(AMSImage.SpPrmId, _id),
                                     new SqlParameter(AMSImage.SpPrmArg, AMSImage._spargs.assetid) });

            if (_images == null)
                _images = new List<AMSImage>();
            else
                _images.Clear();

            foreach (DataRow dr in dt.Rows)
                _images.Add(new AMSImage(this, dr));
        }

        public void LoadPurchaseData()
        {
            DataTable dt = SendReadRequest(PurchaseData.SpSelect,
                new SqlParameter[] { new SqlParameter(PurchaseData.SpPrmId, _id),
                                     new SqlParameter(PurchaseData.SpPrmArg, PurchaseData._spargs.assetid) });

            if (_purchdata == null)
                _purchdata = new List<PurchaseData>();
            else
                _purchdata.Clear();

            foreach (DataRow dr in dt.Rows)
                _purchdata.Add(new PurchaseData(this, dr));
        }

        public void LoadScheduleData()
        {
            DataTable dt = SendReadRequest(ScheduleData.SpSelect,
                new SqlParameter[] { new SqlParameter(ScheduleData.SpPrmId, _id),
                                     new SqlParameter(ScheduleData.SpPrmArg, ScheduleData._spargs.assetid) });

            if (_scheddata == null)
                _scheddata = new List<ScheduleData>();
            else
                _scheddata.Clear();

            foreach (DataRow dr in dt.Rows)
                _scheddata.Add(new ScheduleData(this, dr));
        }

        public void LoadServiceData()
        {
            DataTable dt = SendReadRequest(ServiceData.SpSelect,
                new SqlParameter[] { new SqlParameter(ServiceData.SpPrmId, _id),
                                     new SqlParameter(ServiceData.SpPrmArg, ServiceData._spargs.assetid) });

            if (_servdata == null)
                _servdata = new List<ServiceData>();
            else
                _servdata.Clear();  

            foreach (DataRow dr in dt.Rows)
                _servdata.Add(new ServiceData(this, dr));
        }

        public void LoadWarrantyData()
        {
            DataTable dt = SendReadRequest(WarrantyData.SpSelect,
                new SqlParameter[] { new SqlParameter(WarrantyData.SpPrmId, _id),
                                     new SqlParameter(WarrantyData.SpPrmArg, WarrantyData._spargs.assetid) });

            if (_warrdata == null)
                _warrdata = new List<WarrantyData>();
            else
                _warrdata.Clear();

            foreach (DataRow dr in dt.Rows)
                _warrdata.Add(new WarrantyData(this, dr));
        }

        public bool Save()
        {
            List<SqlParameter> paramlist = new List<SqlParameter>();
            SqlParameter pid = new SqlParameter(_prmid, _id);
            SqlParameter pmeta = new SqlParameter(_prmmeta, _meta);
            SqlParameter pname = new SqlParameter(_prmname, _name);
            SqlParameter pmodel = new SqlParameter(_prmmodel, _mdl);
            SqlParameter pmanuf = new SqlParameter(_prmmanuf, _manuf);
            SqlParameter pmake = new SqlParameter(_prmmake, _make);
            SqlParameter pserial = new SqlParameter(_prmserial, _serial);
            SqlParameter pyear = new SqlParameter(_prmyear, _year);
            SqlParameter pcomm = new SqlParameter(_prmcomm, _comments);
            SqlParameter puserid = new SqlParameter(_prmuserid, _user.ID);

            paramlist.Add(pmeta);
            paramlist.Add(pname);
            paramlist.Add(pmodel);
            paramlist.Add(pmanuf);
            paramlist.Add(pmake);
            paramlist.Add(pserial);
            paramlist.Add(pyear);
            paramlist.Add(pcomm);
            paramlist.Add(puserid);

            // If this is an update request (the id already exists)
            if (_id > 0)
            {
                paramlist.Add(pid);
                return SendWriteRequest(_spupdasset, paramlist) > 0;
            }
            else
            {
                _id = SendWriteRequest(_spinsasset, paramlist);
                return _id > 0;
            }
        }
    }
}